﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：BProdMaterial
// 文件功能描述：
//
// 创建者：名字 (zzl)
// 时间：2021/12/9 8:33:13
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion
using Microsoft.EntityFrameworkCore.Internal;
using System.Text;

namespace KingerRobot.MexicoSailunWMS.SpiService;

internal class BProdMaterial : IProdMaterial
{
    public POProdMaterial CreateMaterial(string materialCode, string materialName)
    {
        var result = new POProdMaterial
        {
            Id = XID.Nextval,
            MaterialCode = materialCode,
            MaterialName = materialName,
        };

        var db = Db.Default;

        db.ProdMaterials.Insert(result);
        return result;
    }

    public POProdMaterial GetMaterialByCode(string materialCode)
    {
        var db = Db.Default;
        var result = db.ProdMaterials
            .Where(t => t.MaterialCode == materialCode).FirstOrDefault();

        return result;
    }
    public List<POProdMaterial> GetMaterialList()
    {
        var db = Db.Default;
        var result = db.ProdMaterials
            .Where(t => t.UseFlag == 1).ToList();

        return result;
    }





    public List<POProdMaterial> GetAllMaterialList()
    {
        var db = Db.Default;
        var result = db.ProdMaterials.ToList();

        return result;
    }

    public List<POProdMaterial> GetMaterialListByIds(List<long?> ids)
    {
        var db = Db.Default;
        var result = db.ProdMaterials
            .Where(t => ids.Contains(t.Id)).Distinct().ToList();

        return result;
    }
    public POProdMaterial GetMaterialById(long materialId)
    {
        var db = Db.Default;
        var result = db.ProdMaterials
            .Where(t => t.Id == materialId).FirstOrDefault();

        return result;
    }
    public int UpdateMaterialById(long id, int expir)
    {
        var db = Db.Default;
        var result = db.ProdMaterials
           .Where(t => t.Id == id).Update(new POProdMaterial
           {
               ExpirDuration = expir,
           });
        return db.SaveChanges();
    }

    public int UpdateMaterialUseFlagById(long id)
    {

        var db = Db.Default;
        var result = 0;
        var material = db.ProdMaterials.Where(t => t.Id == id).FirstOrDefault();
        if (material is not null)
        {
            material.UseFlag = material.UseFlag == 1 ? 0 : 1;
            result = db.SaveChanges();
        }
        return result;
    }
    public int UpdateMaterialCheckById(long id, int ration)
    {
        var db = Db.Default;
        var randomStr = NewRandomSamplingArray(ration);
        var result = db.ProdMaterials
           .Where(t => t.Id == id).Update(new POProdMaterial
           {
               Ration = ration,
               CheckNum = randomStr,
               ScanNum = 0
           });
        return db.SaveChanges();
    }
    private string NewRandomSamplingArray(int samplingCount)
    {
        StringBuilder stringBuilder = new();
        for (int i = 0; i < samplingCount; i++)
        {
            //Guid.NewGuid().GetHashCode() 生成不同种子值，可让random每次产生的值不重复
            Random rd = new Random(Guid.NewGuid().GetHashCode());
            //1 到 100 的随机值
            int num = rd.Next(1, 100);
            //此处int型的 num 和字符串 "," 拼接
            stringBuilder.Append(num + ",");
        }
        return string.Join(",", stringBuilder.ToString().Split(",").OrderBy(t => t));
    }

    public int UpdateMaterialPropertyById(UpdateMaterialPropertyCondition condition)
    {

        var result = -1;

        if (condition.Id == null || condition.Id <= 0) { return result; }

        if (string.IsNullOrWhiteSpace(condition.OutSideDiameter)) { return result; }

        if (string.IsNullOrWhiteSpace(condition.InSideDiameter)) { return result; }

        if (string.IsNullOrWhiteSpace(condition.MaterialHeight)) { return result; }

        if (Convert.ToDecimal(condition.OutSideDiameter.Trim()) <= 0) { return result; }//外径大于0

        if (Convert.ToDecimal(condition.MaterialHeight.Trim()) <= 0) { return result; }//胎高大于0

        if (Convert.ToDecimal(condition.InSideDiameter.Trim()) < 0) { return result; }//内径大于0

        var db = Db.Default;



        if (Convert.ToDecimal(condition.InSideDiameter.Trim()) > 0)
        {
            result = db.ProdMaterials.Where(t => t.Id == condition.Id).Update(new POProdMaterial
            {
                OutsideDiameter = Convert.ToDecimal(condition.OutSideDiameter.Trim()),//外径
                InsideDiameter = Convert.ToDecimal(condition.InSideDiameter.Trim()),//内径
                MaterialHeight = Convert.ToDecimal(condition.MaterialHeight.Trim()),//胎高
                ManualSign = 1//手工维护标志
            });
            //result = db.SaveChanges();
        }
        else if (Convert.ToDecimal(condition.InSideDiameter.Trim()) == 0)
        {

            var material = db.ProdMaterials.Where(t => t.Id == condition.Id).FirstOrDefault();

            if (!string.IsNullOrWhiteSpace(material.Inch))
            {

                result = db.ProdMaterials.Where(t => t.Id == condition.Id).Update(new POProdMaterial()
                {
                    OutsideDiameter = Convert.ToDecimal(condition.OutSideDiameter.Trim()),//外径
                    MaterialHeight = Convert.ToDecimal(condition.MaterialHeight.Trim()),//胎高
                    ManualSign = 1//手工维护标志
                });
            }
        }

        return result;
    }

    public POProdMaterial GetMaterialByMesId(string mesId)
    {
        var db = Db.Default;
        var result = db.ProdMaterials
            .Where(t => t.MesId == mesId).FirstOrDefault();
        return result;
    }

    public List<MaterialCuringInfo> GetMaterialCuringList(decimal num)
    {
        num = num == 0 ? 3 : num;
        var db = Db.Default;
        var result = db.WcsLocSkus.Join(db.RcsLocations, f => f.LocId, s => s.Id, (f, s) => new
        {
            f.SkuId,
            s.LocType,
            s.LocHasSku
        })
         .Where(t => t.LocType == (int)EnumLocType.Location && t.LocHasSku == 1)
         .Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
         {
             s.MaterialId,
             s.Id,
         })
         .Join(db.ProdMaterials, f => f.MaterialId, s => s.Id, (f, s) => new
         {
             f.Id,
             s.MaterialCode,
         }).GroupBy(t => t.MaterialCode)
         .Select(t => new
         {
             MaterialCode = t.Key,
             Count = t.Count()
         })
         .Join(db.MesCuringRequestMaterials, f => f.MaterialCode, s => s.MesMaterialId, (f, s) => new
         {
             f.MaterialCode,
             f.Count,
             s.Id
         }).GroupBy(t => new { t.MaterialCode, t.Count })
            .Select(t => new MaterialCuringInfo
            {
                MaterialCode = t.Key.MaterialCode,
                StockCount = t.Key.Count,
                CuringCount = t.Count(),
                //MinTime = x.OrderBy(t => t.MdTime).Select(t => t.MdTime).FirstOrDefault(),
            }).GroupJoin(db.MesAsrsCuringNormFMess, f => f.MaterialCode, s => s.Greentyreno, (f, s) => new
            {
                MaterialCuringInfo = f,
                MesAsrsCuringNormFMess = s,
            }).SelectMany(f => f.MesAsrsCuringNormFMess.DefaultIfEmpty(), (f, s) => new MaterialCuringInfo
            {
                MaterialCode = f.MaterialCuringInfo.MaterialCode,
                StockCount = f.MaterialCuringInfo.StockCount,
                CuringCount = f.MaterialCuringInfo.CuringCount,
                Quantity = s == null ? num : s.Quantity == 0 ? num : s.Quantity,
            }).OrderByDescending(t => t.StockCount).ToList();

        foreach (var item in result)
        {
            //item.CuringTime = Math.Round(((item.StockCount + item.MesCount) / item.CuringCount / num), 0);
            if (item.Quantity == num)
            {
                item.CuringTime = Math.Round(((item.StockCount + item.MesCount) / item.CuringCount / num), 0);
            }
            else
            {
                item.CuringTime = Math.Round(((item.StockCount + item.MesCount) / item.Quantity ?? 0), 0);
            }
        }

        result = result.OrderByDescending(t => t.CuringTime).ToList();


        return result;
    }
    public List<StockMaterialCount> GetStockMaterialCountList()
    {
        var db = Db.Default;
        var result = db.WcsLocSkus.Join(db.RcsLocations, f => f.LocId, s => s.Id, (f, s) => new
        {
            f.SkuId,
            s.LocType,
            s.LocHasSku
        })
         .Where(t => t.LocType == (int)EnumLocType.Location && t.LocHasSku == 1)
         .Join(db.ProdSkus, f => f.SkuId, s => s.Id, (f, s) => new
         {
             s.MaterialId,
             s.Id,
         })
         .Join(db.ProdMaterials, f => f.MaterialId, s => s.Id, (f, s) => new
         {
             f.Id,
             s.MaterialCode,
             s.MaterialName,
         }).GroupBy(t => new { t.MaterialCode, t.MaterialName } )
         .Select(t => new StockMaterialCount
         {
             MaterialCode = t.Key.MaterialCode,
             MaterialName = t.Key.MaterialName,
             Count = t.Count()
         }).OrderByDescending(t => t.Count).ToList();
        return result;


    }
}
